const crypto = require('crypto');

/**
 * URL规范化工具类
 * 用于处理URL的标准化和生成唯一标识
 */
class UrlNormalizer {
    /**
     * @param {Object} options - 配置选项
     * @param {boolean} options.ignoreParamOrder - 是否忽略参数顺序
     * @param {string[]} options.ignoreParams - 需要忽略的参数列表
     * @param {Object} options.siteRules - 网站特定的规则
     */
    constructor(options = {}) {
        this.options = {
            // 是否忽略参数顺序
            ignoreParamOrder: true,
            // 忽略的通用参数列表
            ignoreParams: [
                'utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',
                '_t', 'timestamp', 'from', 'ref', 'lang', 'locale'
            ],
            // 网站特定的规则
            siteRules: {
                'zhihu.com': {
                    ignoreParams: ['utm_id', 'source']
                },
                'github.com': {
                    ignoreParams: ['ref_cta', 'ref_loc', 'ref_page']
                }
            },
            ...options
        };
    }

    /**
     * 规范化URL
     * @param {string} url - 输入URL
     * @returns {string} 规范化后的URL
     */
    normalize(url) {
        try {
            const urlObj = new URL(url);
            
            // 获取该网站的特定规则
            const siteRule = this.getSiteRule(urlObj.hostname);
            const ignoreParams = [...this.options.ignoreParams, ...(siteRule?.ignoreParams || [])];
            
            // 处理查询参数
            const searchParams = new URLSearchParams(urlObj.search);
            const filteredParams = new Map();
            
            // 过滤和排序参数
            for (const [key, value] of searchParams.entries()) {
                if (!ignoreParams.includes(key)) {
                    filteredParams.set(key, value);
                }
            }
            
            // 重建URL，可选是否排序参数
            const normalizedParams = this.options.ignoreParamOrder 
                ? new URLSearchParams([...filteredParams.entries()].sort())
                : new URLSearchParams(filteredParams);
            
            // 构建规范化的URL
            urlObj.search = normalizedParams.toString();
            
            // 移除末尾的斜杠
            let normalizedUrl = urlObj.toString();
            if (normalizedUrl.endsWith('/')) {
                normalizedUrl = normalizedUrl.slice(0, -1);
            }
            
            return normalizedUrl;
        } catch (error) {
            console.error('URL规范化失败:', error);
            return url; // 如果处理失败，返回原始URL
        }
    }

    /**
     * 获取网站特定的规则
     * @param {string} hostname - 主机名
     * @returns {Object|undefined} 网站规则
     */
    getSiteRule(hostname) {
        return Object.entries(this.options.siteRules)
            .find(([domain]) => hostname.includes(domain))?.[1];
    }

    /**
     * 获取URL的唯一标识
     * @param {string} url - 输入URL
     * @returns {string} URL的唯一标识（8位hash）
     */
    getUrlIdentifier(url) {
        const normalizedUrl = this.normalize(url);
        var hash = crypto.createHash('md5')
            .update(normalizedUrl)
            .digest('hex');
        return hash.length > 20 ? hash.slice(0, 20) : hash;
    }
}

module.exports = UrlNormalizer;
